package com.yp.infrastructure.axon.interceptor.command;

import com.yp.infrastructure.axon.interceptor.BaseMessageHandlerInterceptor;
import com.yp.infrastructure.axon.interceptor.IAxonCommandHandlerInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.axonframework.commandhandling.CommandMessage;
import org.axonframework.messaging.MessageDispatchInterceptor;

import javax.annotation.Nonnull;
import java.util.List;
import java.util.function.BiFunction;

/**
 * ref:
 * <a href="https://docs.axoniq.io/reference-guide/axon-framework/messaging-concepts/message-intercepting">官方文档(MessageHandler)</a>
 * Message dispatch interceptors are invoked when a command is dispatched on a command bus.{@link org.axonframework.commandhandling.CommandBus}
 * They have the ability to alter the command message by adding metadata.
 * They can also block the command by throwing an exception.
 * <b>These interceptors are always invoked on the thread that dispatches the command</b>.
 *
 * <p>
 * 如果要对EventHandler进行拦截，将本类的泛型{@link CommandMessage}改为{@link org.axonframework.eventhandling.EventMessage}
 * </p>
 */

@Slf4j
public class CmdMessageDispatcherInterceptor
        extends BaseMessageHandlerInterceptor implements MessageDispatchInterceptor<CommandMessage<?>> {

    private final IAxonCommandHandlerInterceptor handler;

    public CmdMessageDispatcherInterceptor(@Nonnull IAxonCommandHandlerInterceptor handler) {
        this.handler = handler;
    }


    @Nonnull
    @Override
    public CommandMessage<?> handle(@Nonnull CommandMessage<?> message) {
        return MessageDispatchInterceptor.super.handle(message);
    }

    @Nonnull
    @Override
    public BiFunction<Integer, CommandMessage<?>, CommandMessage<?>> handle(@Nonnull List<? extends CommandMessage<?>> messages) {
        return (i, commandMessage) -> {
            handler.onCommandMessageDispatcherInterceptor(commandMessage.getPayload());
            return commandMessage;
        };
    }
}
